package com.service.quartz.service;

import com.alibaba.fastjson.JSON;
import com.service.quartz.constant.TaskConstant;
import com.service.quartz.dao.TaskDao;
import com.service.quartz.dao.TaskLogDao;
import com.service.quartz.dto.NotifyResponse;
import com.service.quartz.model.TaskLogModel;
import com.service.quartz.model.TaskModel;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
@Slf4j
public class TaskService implements Job {

    @Autowired
    private TaskDao taskDao;
    @Autowired
    private HttpJobService httpJobService;
    @Autowired
    private TaskLogDao taskLogDao;

    public void execute(JobExecutionContext context) {
        int try_num = 0;
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        int id = jobDataMap.getIntValue("id");
        log.info("执行任务id: {}", id);
        TaskModel taskModel = taskDao.getById(id);
        if (taskModel == null) {
            // 任务无需执行
            log.debug("任务不存在 id:{}", id);
            return;
        }
        if (StringUtils.isEmpty(taskModel.getNotifyUrl())) {
            log.error("任务通知url为空 {}", taskModel);
        }
        if (1 == taskModel.getNotifyState()) {
            // 任务无需执行
            log.error("任务已通知 {}", taskModel);
            return;
        }
        log.info("{}", taskModel);
        TaskLogModel taskLogModel = new TaskLogModel();

        int max_try = taskModel.getMaxRetry();
        while (++try_num <= max_try) {
            try {
                String result = httpJobService.notify(taskModel);
                NotifyResponse notifyResponse = JSON.parseObject(result, NotifyResponse.class);

                taskLogModel.setNotifyResult(result);
                taskModel.setNotifyResult(result);
                if (notifyResponse == null || notifyResponse.getCode() != 200) {
                    taskModel.setNotifyState(TaskConstant.NOTIFY_STATE_FAIL);

                    taskLogModel.setNotifyState(TaskConstant.NOTIFY_STATE_RETRY);
                    taskLogModel.setTask(taskModel);
                    taskLogDao.save(taskLogModel);
                    throw new Exception(result);
                } else {
                    taskModel.setNotifyState(TaskConstant.NOTIFY_STATE_SUCCESS);
                    taskLogModel.setNotifyState(TaskConstant.NOTIFY_STATE_SUCCESS);
                    taskLogModel.setTask(taskModel);
                    taskLogDao.save(taskLogModel);
                    break;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
                taskLogModel.setNotifyResult(exception.getMessage());
                taskLogModel.setTask(taskModel);
                if (try_num == max_try) {
                    taskLogModel.setNotifyState(TaskConstant.NOTIFY_STATE_FAIL);
                    taskModel.setNotifyState(TaskConstant.NOTIFY_STATE_FAIL);
                    break;
                } else {
                    taskLogModel.setNotifyState(TaskConstant.NOTIFY_STATE_RETRY);
                }
            }
        }
        taskLogDao.save(taskLogModel);
        taskDao.save(taskModel);
        // TODO 如果执行失败，需要发送警告通知
    }

}

